Shader "BaseWithPlaneShadow"
//1.压扁
//2.投影偏移
//3.投影拉长
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _ShadowOffset ("Shadow Offset(XZ),shadowHeigth(Y)", Vector) = (0,0,0,0)
    }

    SubShader
    {
            //半透明物体，先画远再画近
            //不透明：从前往后（节省性能）
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            Name "BasePass" //第一个pass画角色

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            

            struct appData
            {
                float4 pos : POSITION; //pos in local space 自己的空间
                float2 uv : TEXCOORD0;
            }; //结构体后一定加分号

            struct v2f
            {
                float4 pos : SV_POSITION;// pos in screen space 屏幕空间
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert(appData v)// 输入
            {
                v2f o;// 输出
                o.vertex  = UnityObjectToClipPos(v.vertex); // 顶点坐标转换;
                output.uv = TRANSFORM_TEX(v.uv,_MainTex) ;// 纹理坐标直接传递给frag，不用乘
                return o;
                //为什么不在自身模型空间压扁，而是在世界空间压扁？
                //因为角色会旋转，压扁的阴影也跟着转
            }

            // 顶点的输出是像素的输入 
            half4 frag(v2f i) : SV_Target
            {
                // half4 col = tex2D(_MainTex, output.uv);
                half4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
    
        }

        Pass
        {
            Name "PlanarShadow"
            Blend SrcAlpha OneMinusSrcAlpha //混合模式 1-源颜色
            Stencil
            {
                Ref 1 // 1 为1的地方才渲染
                Comp NotEqual // 比较方式
                Pass Replace // 当模版测试通过，根据stencilOperation的值，对模版缓冲处理
                Fail Keep // 测试失败保持模版值
            }



            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            

            struct VertInput
            {
                float4 pos : POSITION; //pos in local space 自己的空间
                float2 uv : TEXCOORD0;
            }; //结构体后一定加分号

            struct v2f
            {
                float4 pos : SV_POSITION;// pos in screen space 屏幕空间
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Color;
            float4 _ShadowOffset;

            v2f vert(appData v)// 输入
            {
                v2f o;// 输出
                // o.vertex = UnityObjectToClipPos(input.pos); // 顶点坐标转换
              //全部变成脚底的高度值
              float4 vWorld = mul(unity_ObjectToWorld, v.vertex);//自身坐标变到世界空间
              vWorld.xz += _ShadowOffset.xz * (vWorld.y - _ShadowOffset.y);//投影偏移
              vWorld.y = _ShadowOffset.y;//变到脚底的高度值

                // Window ->Analysis ->Frame Debugger //TA的性能分析工具
                // 还差摄像机和投影矩阵变换！PV矩阵组合，就不用乘两次
                o.vertex  = mul(UNITY_MATRIX_VP, vWorld);
                o.uv = v.uv;// 纹理坐标直接传递给frag，不用乘
                return output;
                //为什么不在自身模型空间压扁，而是在世界空间压扁？
                //因为角色会旋转，压扁的阴影也跟着转
            }

            // 顶点的输出是像素的输入 
            half4 frag(v2f i) : SV_Target
            {
                // half4 col = tex2D(_MainTex, output.uv);
                // half4 col = tex2D(_MainTex, i.uv);
                return float(vec3(0.0),0.5);//黑色
            }
            ENDCG
    
        }
      
    }
}
//表面函数作为模型顶点作为输入
// 优缺点】
// 不打灯：不计算光照
// 1。如何实现多光源屏幕阴影？
// 2。如何实现阴影渐隐